// Main script for module 'Tween'

_TweenData _tweens[MAX_TWEENS]; // Stores all the tweens in the game

///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////

/**
 * Gets red value from color integer
 * @param color in AGS-style integer color value
 * @return integer with red value
 */
int GetRFromColor(int color) {
  float floatColor = IntToFloat(color);
  int result = FloatToInt(floatColor / 2048.0) * 8;

  return result;
}

/**
 * Gets green value from color integer
 * @param color in AGS-style integer color value
 * @return integer with green value
 */
int GetGFromColor(int color) {
  float floatColor = IntToFloat(color);
  int result = FloatToInt(( floatColor - IntToFloat(FloatToInt(floatColor / 2048.0) * 2048)) / 64.0) * 8;

  return result;
}

/**
 * Gets blue value from color integer
 * @param color in AGS-style integer color value
 * @return integer with blue value
 */
int GetBFromColor(int color) {
  float floatColor = IntToFloat(color);
  float withoutR = floatColor - IntToFloat(FloatToInt(floatColor / 2048.0) * 2048);
  int withoutRInt = FloatToInt(withoutR);
  float withoutG = withoutR - IntToFloat(FloatToInt(withoutR / 64.0) * 64);
  int withoutGInt = FloatToInt(withoutG);
  int result = withoutGInt * 8;

  if (result > 255) {
    result = (withoutGInt - 31) * 8 - 1;
  }

  return result;
}

/**
 * Converts seconds to AGS "loops"
 *
 * @params seconds the number of seconds
 * @return integer value with the number of loops equivalent to that second
 */
int SecondsToLoops(float seconds) {
  return FloatToInt(IntToFloat(GetGameSpeed()) * seconds, eRoundNearest);
}

function WaitSeconds(float seconds) {
  Wait(SecondsToLoops(seconds));
}

/**
 * Linear Interpolation
 *
 * @param from is the start value
 * @param to is the final value
 * @param amount is from 0.0 to 1.0, how far along in the lerp it is
 * @return integer value with the current value
 */
int Lerp(int from, int to, float amount) {
  return FloatToInt(IntToFloat(from) + IntToFloat(to - from) * amount, eRoundUp);
}

float ComputeTiming(int currentTime, int duration, TweenTiming timingType) {
  float timing = IntToFloat(currentTime) / IntToFloat(duration);

  if (timingType != eLinearTween) {
    float timing2 = Maths.RaiseToPower(timing, 2.0);

    if (timingType == eEaseInTween) {
      timing = ((3.0 * timing2) - (timing2 * timing)) * 0.5;
    }
    else if (timingType == eEaseOutTween) {
      timing = ((3.0 * timing) - (timing2 * timing)) * 0.5;
    }
    else if (timingType == eEaseInEaseOutTween) {
      timing = (3.0 * timing2) - (2.0 * timing * timing2);
    }
  }

  return timing;
}

///////////////////////////////////////////////////////////////////////////////
// Tween Internal Step
///////////////////////////////////////////////////////////////////////////////

/**
 * Makes any tween change on every frame
 * @param amount is from 0.0 to 1.0
 */
function _TweenData::step(float amount) {
  // GUI step
  if (this.type == _eTweenGUIPosition) {
    this.guiRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  if (this.type == _eTweenGUISize) {
    this.guiRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenGUITransparency) {
    // Workaround for Popup Modal GUIs. If the scripter is fading this in, then make it vsible.
    if (this.frameCount == 0 && this.guiRef.Visible == false && this.guiRef.Transparency == 100) {
      this.guiRef.Visible = true;
    }

    this.guiRef.Transparency = Lerp(this.fromX, this.toX, amount);

    // Workaround for Popup Modal GUIs. If the scripter is fading this out, then make it invisble.
    if (this.frameCount == this.duration && this.guiRef.Visible == true && this.guiRef.Transparency == 100) {
      this.guiRef.Visible = false;
    }
  }
  else if (this.type == _eTweenGUIZOrder) {
    this.guiRef.ZOrder = Lerp(this.fromX, this.toX, amount);
  }
  /// OBJECT step
  else if (this.type == _eTweenObjectPosition) {
    this.objectRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenObjectTransparency) {
    if (this.frameCount == 0 && this.objectRef.Visible == false && this.objectRef.Transparency == 100) {
      this.objectRef.Visible = true;
    }

    this.objectRef.Transparency = Lerp(this.fromX, this.toX, amount);

    if (this.frameCount == this.duration && this.objectRef.Visible == true && this.objectRef.Transparency == 100) {
      this.objectRef.Visible = false;
    }
  }
  /// CHARACTER step
  else if (this.type == _eTweenCharacterPosition) {
    this.characterRef.x = Lerp(this.fromX, this.toX, amount);
    this.characterRef.y = Lerp(this.fromY, this.toY, amount);
  }
  else if (this.type == _eTweenCharacterScaling) {
    this.characterRef.Scaling = Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenCharacterTransparency) {
    this.characterRef.Transparency = Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenCharacterAnimationSpeed) {
    this.characterRef.AnimationSpeed = Lerp(this.fromX, this.toX, amount);
  }
  /// REGION step
  else if (this.type == _eTweenRegionLightLevel) {
    this.regionRef.LightLevel = Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenRegionTintR) {
    int saturation = this.regionRef.TintSaturation;
    if (saturation < 0) saturation = 0;
    this.regionRef.Tint(Lerp(this.fromX, this.toX, amount), this.regionRef.TintGreen, this.regionRef.TintBlue, saturation);
  }
  else if (this.type == _eTweenRegionTintG) {
    int saturation = this.regionRef.TintSaturation;
    if (saturation < 0) saturation = 0;
    this.regionRef.Tint(this.regionRef.TintRed, Lerp(this.fromX, this.toX, amount), this.regionRef.TintBlue, saturation);
  }
  else if (this.type == _eTweenRegionTintB) {
    int saturation = this.regionRef.TintSaturation;
    if (saturation < 0) saturation = 0;
    this.regionRef.Tint(this.regionRef.TintRed, this.regionRef.TintGreen, Lerp(this.fromX, this.toX, amount), saturation);
  }
  else if (this.type == _eTweenRegionTintAmount) {
    int saturation = Lerp(this.fromX, this.toX, amount);
    if (saturation < 0) saturation = 0;
    this.regionRef.Tint(this.regionRef.TintRed, this.regionRef.TintGreen, this.regionRef.TintBlue, saturation);
  }
  /// LABEL step
  else if (this.type == _eTweenLabelPosition) {
    this.labelRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenLabelSize) {
    this.labelRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenLabelColorR) {
    this.labelRef.TextColor = Game.GetColorFromRGB(Lerp(this.fromX, this.toX, amount), GetGFromColor(this.labelRef.TextColor), GetBFromColor(this.labelRef.TextColor));
  }
  else if (this.type == _eTweenLabelColorG) {
    this.labelRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.labelRef.TextColor), Lerp(this.fromX, this.toX, amount), GetBFromColor(this.labelRef.TextColor));
  }
  else if (this.type == _eTweenLabelColorB) {
    this.labelRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.labelRef.TextColor), GetGFromColor(this.labelRef.TextColor), Lerp(this.fromX, this.toX, amount));
  }
  /// BUTTON step
  else if (this.type == _eTweenButtonPosition) {
    this.buttonRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenButtonSize) {
    this.buttonRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenButtonColorR) {
    this.buttonRef.TextColor = Game.GetColorFromRGB(Lerp(this.fromX, this.toX, amount), GetGFromColor(this.buttonRef.TextColor), GetBFromColor(this.buttonRef.TextColor));
  }
  else if (this.type == _eTweenButtonColorG) {
    this.buttonRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.buttonRef.TextColor), Lerp(this.fromX, this.toX, amount), GetBFromColor(this.buttonRef.TextColor));
  }
  else if (this.type == _eTweenButtonColorB) {
    this.buttonRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.buttonRef.TextColor), GetGFromColor(this.buttonRef.TextColor), Lerp(this.fromX, this.toX, amount));
  }
  /// TEXTBOX step
  else if (this.type == _eTweenTextBoxPosition) {
    this.textBoxRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenTextBoxSize) {
    this.textBoxRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenTextBoxColorR) {
    this.textBoxRef.TextColor = Game.GetColorFromRGB(Lerp(this.fromX, this.toX, amount), GetGFromColor(this.textBoxRef.TextColor), GetBFromColor(this.textBoxRef.TextColor));
  }
  else if (this.type == _eTweenTextBoxColorG) {
    this.textBoxRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.textBoxRef.TextColor), Lerp(this.fromX, this.toX, amount), GetBFromColor(this.textBoxRef.TextColor));
  }
  else if (this.type == _eTweenTextBoxColorB) {
    this.textBoxRef.TextColor = Game.GetColorFromRGB(GetRFromColor(this.textBoxRef.TextColor), GetGFromColor(this.textBoxRef.TextColor), Lerp(this.fromX, this.toX, amount));
  }
  /// LISTBOX step
  else if (this.type == _eTweenListBoxPosition) {
    this.listBoxRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenListBoxSize) {
    this.listBoxRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenListBoxSelectedItem) {
    this.listBoxRef.SelectedIndex =  Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenListBoxTopItem) {
    this.listBoxRef.TopItem = Lerp(this.fromX, this.toX, amount);
  }
  /// SLIDER step
  else if (this.type == _eTweenSliderPosition) {
    this.sliderRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenSliderSize) {
    this.sliderRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenSliderValue) {
    this.sliderRef.Value =  Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenSliderHandleOffset) {
    this.sliderRef.HandleOffset = Lerp(this.fromX, this.toX, amount);
  }
  /// INVWINDOW step
  else if (this.type == _eTweenInvWindowPosition) {
    this.invWindowRef.SetPosition(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenInvWindowSize) {
    this.invWindowRef.SetSize(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenInvWindowTopItem) {
    this.invWindowRef.TopItem = Lerp(this.fromX, this.toX, amount);
  }
  /// MISC step
  else if (this.type == _eTweenViewportX) {
    SetViewport(Lerp(this.fromX, this.toX, amount), GetViewportY());
  }
  else if (this.type == _eTweenViewportY) {
    SetViewport(GetViewportX(), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenViewportXY) {
    SetViewport(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  else if (this.type == _eTweenGamma) {
    System.Gamma = Lerp(this.fromX, this.toX, amount);
  }
  else if (this.type == _eTweenShakeScreen) {
    ShakeScreenBackground(Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount), 1);
  }
  else if (this.type == _eTweenAreaScaling) {
    SetAreaScaling(this.extraParam1, Lerp(this.fromX, this.toX, amount), Lerp(this.fromY, this.toY, amount));
  }
  // AUDIO step
  else if (this.type == _eTweenSpeechVolume) {
    SetSpeechVolume(Lerp(this.fromX, this.toX, amount));
  }
  // 3.2+ strict audio
#ifndef STRICT_AUDIO
  else if (this.type == _eTweenMusicMasterVolume) {
    SetMusicMasterVolume(Lerp(this.fromX, this.toX, amount));
  }
  else if (this.type == _eTweenDigitalMasterVolume) {
    SetDigitalMasterVolume(Lerp(this.fromX, this.toX, amount));
  }
  else if (this.type == _eTweenSoundVolume) {
    SetSoundVolume(Lerp(this.fromX, this.toX, amount));
  }
  else if (this.type == _eTweenChannelVolume) {
    SetChannelVolume(this.extraParam1, Lerp(this.fromX, this.toX, amount));
  }
#endif
  // TODO: Support New-Style 3.2+ Audio System
}

/**
 * Resets and stops all the tweens
 */
function CleanupTweens() {
  short i = 0;

  while (i < MAX_TWEENS) {
    if (_tweens[i].duration != -1) {
      _tweens[i].step(0.0);
      _tweens[i].duration = -1;
    }

    i++;
  }
}

///////////////////////////////////////////////////////////////////////////////
// AGS Events
///////////////////////////////////////////////////////////////////////////////

function game_start() {
  // Initialize all the internal tween data on game start
  short i = 0;
  while (i < MAX_TWEENS) {
    _tweens[i].duration = -1;
    i++;
  }

  System.VSync = true;
}

function repeatedly_execute_always() {
  // Steps through every active tween
  short i = 0;

  while (i < MAX_TWEENS) {
    if (_tweens[i].duration > 0) {
      // Compute the amount based on the timing type
      float amount = ComputeTiming(
        _tweens[i].frameCount,
        _tweens[i].duration,
        _tweens[i].timing
        );

      // Update the tween
      _tweens[i].step(amount);
      _tweens[i].frameCount++;

      // Repeat tween if needed
      if (_tweens[i].frameCount > _tweens[i].duration) {
        if (_tweens[i].style == eRepeatTween) {
          _tweens[i].frameCount = 0;
        }
        else if (_tweens[i].style == eReverseRepeatTween) {
          short fromX = _tweens[i].toX;
          short fromY = _tweens[i].toY;

          _tweens[i].toX = _tweens[i].fromX;
          _tweens[i].toY = _tweens[i].fromY;
          _tweens[i].fromX = fromX;
          _tweens[i].fromY = fromY;

          _tweens[i].frameCount = 0;
        }
        else {
          _tweens[i].duration = -1;
        }
      }
    }

    i++;
  }
}

function on_event(EventType event, int data) {
  if (event == eEventLeaveRoom) {
    // If the player leaves the room, reset and stop tweens
    CleanupTweens();
  }
}

///////////////////////////////////////////////////////////////////////////////
// Tween Construction
///////////////////////////////////////////////////////////////////////////////

/*
 * Finds and returns an available tween spot
 *
 * @return integer index in the _tweens array that is available.
 */
int GetAvailableTweenSpot() {
  short i = 0;
  short spot = -1;

  // Pretty simple linear search for an available spot
  while (i < MAX_TWEENS && spot == -1) {
    if (_tweens[i].duration == -1) {
      spot = i;
    }

    i++;
  }

#ifdef DEBUG
  // Let the scripter know that tweens are maxed out, but ignore it completely in the non-debug version.
  if (spot == -1) {
    AbortGame(
      "Cannot create new tween because the Tween module is currently playing %d tween(s), which is the maximum. You can increase this max number on the Tween module script header.",
      MAX_TWEENS
      );
  }
#endif

  return spot;
}

int StartTween(short index, _TweenType type, float seconds, short toX, short toY,
  short fromX, short fromY, short extraParam1, TweenTiming timing, TweenStyle style) {
#ifdef DEBUG
  // "Assert" the index. This should not happen to scripters.
  if (index < 0 || index >= MAX_TWEENS) {
    AbortGame("Cannot create Tween. Invalid index!");
  }
#endif

  _tweens[index].type = type;
  _tweens[index].toX = toX;
  _tweens[index].toY = toY;
  _tweens[index].fromX = fromX;
  _tweens[index].fromY = fromY;
  _tweens[index].extraParam1 = extraParam1;
  _tweens[index].duration = SecondsToLoops(seconds);
  _tweens[index].frameCount = 0;
  _tweens[index].timing = timing;
  _tweens[index].style = style;

  if (_tweens[index].style == eBlockTween) {
    Wait(_tweens[index].duration + 1);
  }
  else {
    return _tweens[index].duration + 1;
  }

  return 1;
}

// Starts a new tween. Covers GUI, Object, Character, Region and Labels
int StartTween1(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
            GUI* guiRef, Object* objectRef, Character* characterRef, Region* regionRef, Label* labelRef,
            TweenTiming timing, TweenStyle style) {
  short spot = GetAvailableTweenSpot();

  if (spot != -1) {
    _tweens[spot].guiRef = guiRef;
    _tweens[spot].objectRef = objectRef;
    _tweens[spot].characterRef = characterRef;
    _tweens[spot].regionRef = regionRef;
    _tweens[spot].labelRef = labelRef;

    return StartTween(spot, type, seconds, toX, toY, fromX, fromY, extraParam1, timing, style);
  }

  return 1;
}

// Starts a new tween. Covers Button, TextBox, ListBox, Slider, and InvWindow
int StartTween2(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
            Button* buttonRef, TextBox* textBoxRef, ListBox* listBoxRef, Slider* sliderRef, InvWindow* invWindowRef,
            TweenTiming timing, TweenStyle style) {
  short spot = GetAvailableTweenSpot();

  if (spot != -1) {
    _tweens[spot].buttonRef = buttonRef;
    _tweens[spot].textBoxRef = textBoxRef;
    _tweens[spot].listBoxRef = listBoxRef;
    _tweens[spot].sliderRef = sliderRef;
    _tweens[spot].invWindowRef = invWindowRef;

    return StartTween(spot, type, seconds, toX, toY, fromX, fromY, extraParam1, timing, style);
  }

  return 1;
}

int StartGUITween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    GUI* guiRef, TweenTiming timing, TweenStyle style) {
  return StartTween1(
	  type, seconds, toX, toY, fromX, fromY, extraParam1,
    guiRef, null, null, null, null,
    timing, style);
}

int StartObjectTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Object* objectRef, TweenTiming timing, TweenStyle style) {
  return StartTween1(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, objectRef, null, null, null,
    timing, style);
}

int StartCharacterTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Character* characterRef, TweenTiming timing, TweenStyle style) {
  return StartTween1(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, characterRef, null, null,
    timing, style);
}

int StartRegionTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Region* regionRef, TweenTiming timing, TweenStyle style) {
  return StartTween1(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, null, regionRef, null,
    timing, style);
}

int StartLabelTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Label* labelRef, TweenTiming timing, TweenStyle style) {
  return StartTween1(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, null, null, labelRef,
    timing, style);
}

int StartButtonTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Button* buttonRef, TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    buttonRef, null, null, null, null,
    timing, style);
}

int StartTextBoxTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    TextBox* textBoxRef, TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, textBoxRef, null, null, null,
    timing, style);
}

int StartListBoxTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    ListBox* listBoxRef, TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, listBoxRef, null, null,
    timing, style);
}

int StartSliderTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    Slider* sliderRef, TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, null, sliderRef, null,
    timing, style);
}

int StartInvWindowTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    InvWindow* invWindowRef, TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, null, null, invWindowRef,
    timing, style);
}

int StartMiscTween(_TweenType type, float seconds, short toX, short toY, short fromX, short fromY, short extraParam1,
    TweenTiming timing, TweenStyle style) {
  return StartTween2(
    type, seconds, toX, toY, fromX, fromY, extraParam1,
    null, null, null, null, null,
    timing, style);
}

// GUI Tweens
int TweenGUIPosition(GUI* guiRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartGUITween(_eTweenGUIPosition, seconds, toX, toY, guiRef.X, guiRef.Y, 0, guiRef, timing, style);
}
int TweenGUIZOrder(GUI* guiRef, float seconds, short toZOrder, TweenTiming timing, TweenStyle style) {
  return StartGUITween(_eTweenGUIZOrder, seconds, toZOrder, 0, guiRef.ZOrder, 0, 0, guiRef, timing, style);
}
int TweenGUITransparency(GUI* guiRef, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return StartGUITween(_eTweenGUITransparency, seconds, toTransparency, 0, guiRef.Transparency, 0, 0, guiRef, timing, style);
}
int TweenGUISize(GUI* guiRef, float seconds, short toWidth, short toHeight, TweenTiming timing, TweenStyle style) {
  return StartGUITween(_eTweenGUISize, seconds, toWidth, toHeight, guiRef.Width, guiRef.Height, 0, guiRef, timing, style);
}

// OBJECT Tweens
int TweenObjectPosition(Object* objectRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartObjectTween(_eTweenObjectPosition, seconds, toX, toY, objectRef.X, objectRef.Y, 0, objectRef, timing, style);
}
int TweenObjectTransparency(Object* objectRef, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return StartObjectTween(_eTweenObjectTransparency, seconds, toTransparency, 0, objectRef.Transparency, 0, 0, objectRef, timing, style);
}
int TweenObjectImage(Object* objectRef, Object* tmpObjectRef, float seconds, short toSprite, TweenTiming timing, TweenStyle style) {
  tmpObjectRef.Graphic = objectRef.Graphic;
  tmpObjectRef.SetPosition(objectRef.X, objectRef.Y);
  tmpObjectRef.Transparency = 0;
  tmpObjectRef.Visible = true;

  objectRef.Transparency = 100;
  objectRef.Graphic = toSprite;

  if (style == eBlockTween) {
    TweenObjectTransparency(tmpObjectRef, seconds, 100, timing, eNoBlockTween);
  }
  else {
    TweenObjectTransparency(tmpObjectRef, seconds, 100, timing, style);
  }
  return TweenObjectTransparency(objectRef, seconds, 0, timing, style);
}

// CHARACTER Tweens
int TweenCharacterPosition(Character* characterRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartCharacterTween(_eTweenCharacterPosition, seconds, toX, toY, characterRef.x, characterRef.y, 0, characterRef, timing, style);
}
int TweenCharacterScaling(Character* characterRef, float seconds, short toScaling, TweenTiming timing, TweenStyle style) {
  if (!characterRef.ManualScaling) {
    characterRef.ManualScaling = true;
  }

  return StartCharacterTween(_eTweenCharacterScaling, seconds, toScaling, 0, characterRef.Scaling, 0, 0, characterRef, timing, style);
}
int TweenCharacterTransparency(Character* characterRef, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return StartCharacterTween(_eTweenCharacterTransparency, seconds, toTransparency, 0, characterRef.Transparency, 0, 0, characterRef, timing, style);
}
int TweenCharacterAnimationSpeed(Character* characterRef, float seconds, short toAnimationSpeed, TweenTiming timing, TweenStyle style) {
  return StartCharacterTween(_eTweenCharacterAnimationSpeed, seconds, toAnimationSpeed, 0, characterRef.AnimationSpeed, 0, 0, characterRef, timing, style);
}

// REGION Tweens
int TweenRegionLightLevel(Region* regionRef, float seconds, short toLightLevel, TweenTiming timing, TweenStyle style) {
  return StartRegionTween(_eTweenRegionLightLevel, seconds, toLightLevel, 0, regionRef.LightLevel, 0, 0, regionRef, timing, style);
}
int TweenRegionTintR(Region* regionRef, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  return StartRegionTween(_eTweenRegionTintR, seconds, toR, 0, regionRef.TintRed, 0, 0, regionRef, timing, style);
}
int TweenRegionTintG(Region* regionRef, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  return StartRegionTween(_eTweenRegionTintG, seconds, toG, 0, regionRef.TintGreen, 0, 0, regionRef, timing, style);
}
int TweenRegionTintB(Region* regionRef, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  return StartRegionTween(_eTweenRegionTintB, seconds, toB, 0, regionRef.TintBlue, 0, 0, regionRef, timing, style);
}
int TweenRegionTintAmount(Region* regionRef, float seconds, short toAmount, TweenTiming timing, TweenStyle style) {
  return StartRegionTween(_eTweenRegionTintAmount, seconds, toAmount, 0, regionRef.TintSaturation, 0, 0, regionRef, timing, style);
}
int TweenRegionTintBlackAndWhite(Region* regionRef, float seconds, TweenTiming timing, TweenStyle style) {
  if (style == eBlockTween) {
    TweenRegionTintR(regionRef, seconds, 255, timing, eNoBlockTween);
    TweenRegionTintG(regionRef, seconds, 255, timing, eNoBlockTween);
    TweenRegionTintB(regionRef, seconds, 255, timing, eNoBlockTween);
  }
  else {
    TweenRegionTintR(regionRef, seconds, 255, timing, style);
    TweenRegionTintG(regionRef, seconds, 255, timing, style);
    TweenRegionTintB(regionRef, seconds, 255, timing, style);
  }
  return TweenRegionTintAmount(regionRef, seconds, 100, timing, style);
}

// LABEL Tweens
int TweenLabelPosition(Label* labelRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartLabelTween(_eTweenLabelPosition, seconds, toX, toY, labelRef.X, labelRef.Y, 0, labelRef, timing, style);
}
int TweenLabelSize(Label* labelRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartLabelTween(_eTweenLabelSize, seconds, toX, toY, labelRef.Width, labelRef.Height, 0, labelRef, timing, style);
}
int TweenLabelColorR(Label* labelRef, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  int fromR = GetRFromColor(labelRef.TextColor);
  return StartLabelTween(_eTweenLabelColorR, seconds, toR, 0, fromR, 0, 0, labelRef, timing, style);
}
int TweenLabelColorG(Label* labelRef, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  int fromG = GetGFromColor(labelRef.TextColor);
  return StartLabelTween(_eTweenLabelColorG, seconds, toG, 0, fromG, 0, 0, labelRef, timing, style);
}
int TweenLabelColorB(Label* labelRef, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  int fromB = GetBFromColor(labelRef.TextColor);
  return StartLabelTween(_eTweenLabelColorB, seconds, toB, 0, fromB, 0, 0, labelRef, timing, style);
}

// BUTTON Tweens
int TweenButtonPosition(Button* buttonRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartButtonTween(_eTweenButtonPosition, seconds, toX, toY, buttonRef.X, buttonRef.Y, 0, buttonRef, timing, style);
}
int TweenButtonSize(Button* buttonRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartButtonTween(_eTweenButtonSize, seconds, toX, toY, buttonRef.Width, buttonRef.Height, 0, buttonRef, timing, style);
}
int TweenButtonColorR(Button* buttonRef, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  int fromR = GetRFromColor(buttonRef.TextColor);
  return StartButtonTween(_eTweenButtonColorR, seconds, toR, 0, fromR, 0, 0, buttonRef, timing, style);
}
int TweenButtonColorG(Button* buttonRef, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  int fromG = GetGFromColor(buttonRef.TextColor);
  return StartButtonTween(_eTweenButtonColorG, seconds, toG, 0, fromG, 0, 0, buttonRef, timing, style);
}
int TweenButtonColorB(Button* buttonRef, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  int fromB = GetBFromColor(buttonRef.TextColor);
  return StartButtonTween(_eTweenButtonColorB, seconds, toB, 0, fromB, 0, 0, buttonRef, timing, style);
}

// TEXT BOX Tweens
int TweenTextBoxPosition(TextBox* textBoxRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartTextBoxTween(_eTweenTextBoxPosition, seconds, toX, toY, textBoxRef.X, textBoxRef.Y, 0, textBoxRef, timing, style);
}
int TweenTextBoxSize(TextBox* textBoxRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartTextBoxTween(_eTweenTextBoxSize, seconds, toX, toY, textBoxRef.Width, textBoxRef.Height, 0, textBoxRef, timing, style);
}
int TweenTextBoxColorR(TextBox* textBoxRef, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  int fromR = GetRFromColor(textBoxRef.TextColor);
  return StartTextBoxTween(_eTweenTextBoxColorR, seconds, toR, 0, fromR, 0, 0, textBoxRef, timing, style);
}
int TweenTextBoxColorG(TextBox* textBoxRef, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  int fromG = GetGFromColor(textBoxRef.TextColor);
  return StartTextBoxTween(_eTweenTextBoxColorG, seconds, toG, 0, fromG, 0, 0, textBoxRef, timing, style);
}
int TweenTextBoxColorB(TextBox* textBoxRef, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  int fromB = GetBFromColor(textBoxRef.TextColor);
  return StartTextBoxTween(_eTweenTextBoxColorB, seconds, toB, 0, fromB, 0, 0, textBoxRef, timing, style);
}

// LIST BOX Tweens
int TweenListBoxPosition(ListBox* listBoxRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartListBoxTween(_eTweenListBoxPosition, seconds, toX, toY, listBoxRef.X, listBoxRef.Y, 0, listBoxRef, timing, style);
}
int TweenListBoxSize(ListBox* listBoxRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartListBoxTween(_eTweenListBoxSize, seconds, toX, toY, listBoxRef.Width, listBoxRef.Height, 0, listBoxRef, timing, style);
}
int TweenListBoxSelectedItem(ListBox* listBoxRef, float seconds, short toSelectedItem, TweenTiming timing, TweenStyle style) {
  return StartListBoxTween(_eTweenListBoxSelectedItem, seconds, toSelectedItem, 0, listBoxRef.SelectedIndex, 0, 0, listBoxRef, timing, style);
}
int TweenListBoxTopItem(ListBox* listBoxRef, float seconds, short toTopItem, TweenTiming timing, TweenStyle style) {
  return StartListBoxTween(_eTweenListBoxTopItem, seconds, toTopItem, 0, listBoxRef.TopItem, 0, 0, listBoxRef, timing, style);
}

// SLIDER Tweens
int TweenSliderPosition(Slider* sliderRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartSliderTween(_eTweenSliderPosition, seconds, toX, toY, sliderRef.X, sliderRef.Y, 0, sliderRef, timing, style);
}
int TweenSliderSize(Slider* sliderRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartSliderTween(_eTweenSliderSize, seconds, toX, toY, sliderRef.Width, sliderRef.Height, 0, sliderRef, timing, style);
}
int TweenSliderValue(Slider* sliderRef, float seconds, short toValue, TweenTiming timing, TweenStyle style) {
  return StartSliderTween(_eTweenSliderValue, seconds, toValue, 0, sliderRef.Value, 0, 0, sliderRef, timing, style);
}
int TweenSliderHandleOffset(Slider* sliderRef, float seconds, short toHandleOffset, TweenTiming timing, TweenStyle style) {
  return StartSliderTween(_eTweenSliderHandleOffset, seconds, toHandleOffset, 0, sliderRef.HandleOffset, 0, 0, sliderRef, timing, style);
}

// INVWINDOW Tweens
int TweenInvWindowPosition(InvWindow* invWindowRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartInvWindowTween(_eTweenInvWindowPosition, seconds, toX, toY, invWindowRef.X, invWindowRef.Y, 0, invWindowRef, timing, style);
}
int TweenInvWindowSize(InvWindow* invWindowRef, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartInvWindowTween(_eTweenInvWindowSize, seconds, toX, toY, invWindowRef.Width, invWindowRef.Height, 0, invWindowRef, timing, style);
}
int TweenInvWindowTopItem(InvWindow* invWindowRef, float seconds, short toTopItem, TweenTiming timing, TweenStyle style) {
  return StartInvWindowTween(_eTweenInvWindowTopItem, seconds, toTopItem, 0, invWindowRef.TopItem, 0, 0, invWindowRef, timing, style);
}

// MISC Tweens
int TweenViewportX(float seconds, short toX, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenViewportX, seconds, toX, 0, GetViewportX(), 0, 0, timing, style);
}
int TweenViewportY(float seconds, short toY, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenViewportY, seconds, 0, toY, 0, GetViewportY(), 0, timing, style);
}
int TweenViewportXY(float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenViewportXY, seconds, toX, toY, GetViewportX(), GetViewportY(), 0, timing, style);
}
int TweenGamma(float seconds, short toGamma, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenGamma, seconds, toGamma, 0, System.Gamma, 0, 0, timing, style);
}
int TweenShakeScreen(float seconds, short fromDelay, short toDelay, short fromAmount, short toAmount, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenShakeScreen, seconds,  toDelay, toAmount, fromDelay, fromAmount, 0, timing, style);
}
int TweenAreaScaling(float seconds, short area, short fromMin, short toMin, short fromMax, short toMax, TweenTiming timing, TweenStyle style) {
   return StartMiscTween(_eTweenAreaScaling, seconds, toMin, toMax, fromMin, fromMax, area, timing, style);
}

// AUDIO Tweens
int TweenSpeechVolume(float seconds, short fromVolume, short toVolume, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenSpeechVolume, seconds, toVolume, 0, fromVolume, 0, 0, timing, style);
}
#ifndef STRICT_AUDIO
int TweenMusicMasterVolume(float seconds, short fromVolume, short toVolume, TweenTiming timing, TweenStyle style) {
  return StartMiscTween(_eTweenMusicMasterVolume, seconds, toVolume, 0, fromVolume, 0, 0, timing, style);
}
int TweenDigitalMasterVolume(float seconds, short fromVolume, short toVolume, TweenTiming timing, TweenStyle style) {
   return StartMiscTween(_eTweenDigitalMasterVolume, seconds, toVolume, 0, fromVolume, 0, 0, timing, style);
}
int TweenSoundVolume(float seconds, short fromVolume, short toVolume, TweenTiming timing, TweenStyle style) {
   return StartMiscTween(_eTweenSoundVolume, seconds, toVolume, 0, fromVolume, 0, 0, timing, style);
}
int TweenChannelVolume(float seconds, short channel, short fromVolume, short toVolume, TweenTiming timing, TweenStyle style) {
   return StartMiscTween(_eTweenChannelVolume, seconds, toVolume, 0, fromVolume, 0, channel, timing, style);
}
#endif

///////////////////////////////////////////////////////////////////////////////
// Tween Stoppers
///////////////////////////////////////////////////////////////////////////////

/**
  * Stops a tween
  *
  * @param index which tween in the _tweens array to stop
  * @param result how to stop the tween:
  *   ePauseTween will leave it as it is
  *   eFinishTween will carry it to the end
  *   eResetTween will bring it back to where it was
  */
function StopTween(short index, TweenStopResult result)
{
  if (_tweens[index].duration != -1) {
    if (result == eFinishTween) {
      _tweens[index].step(1.0);
    }
    else if (result == eResetTween) {
      _tweens[index].step(0.0);
    }
    
    _tweens[index].duration = -1;
  }
}

function TweenStopAllForGUI(GUI* guiRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].guiRef == guiRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForObject(Object* objectRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].objectRef == objectRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForCharacter(Character* characterRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].characterRef == characterRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForRegion(Region* regionRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].regionRef == regionRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForLabel(Label* labelRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].labelRef == labelRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForButton(Button* buttonRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].buttonRef == buttonRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForTextBox(TextBox* textBoxRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].textBoxRef == textBoxRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForListBox(ListBox* listBoxRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].listBoxRef == listBoxRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForSlider(Slider* sliderRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].sliderRef == sliderRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAllForInvWindow(InvWindow* invWindowRef, TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    if (_tweens[i].invWindowRef == invWindowRef) {
      StopTween(i, result);
    }
    i++;
  }
}

function TweenStopAll(TweenStopResult result) {
  short i = 0;
  while (i < MAX_TWEENS) {
    StopTween(i, result);
    i++;
  }
}

///////////////////////////////////////////////////////////////////////////////
// Extender Functions (FOR AGS 3.0 OR LATER ONLY):
///////////////////////////////////////////////////////////////////////////////

#ifdef AGS_SUPPORTS_IFVER
#ifver 3.0
int TweenPosition(this GUI*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenGUIPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this Object*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenObjectPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this Character*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenCharacterPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this Label*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenLabelPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this Button*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenButtonPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this TextBox*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenTextBoxPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this ListBox*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenListBoxPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this Slider*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenSliderPosition(this, seconds, toX, toY, timing, style);
}

int TweenPosition(this InvWindow*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenInvWindowPosition(this, seconds, toX, toY, timing, style);
}

int TweenTransparency(this GUI*, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return TweenGUITransparency(this, seconds, toTransparency, timing, style);
}

int TweenTransparency(this Object*, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return TweenObjectTransparency(this, seconds, toTransparency, timing, style);
}

int TweenTransparency(this Character*, float seconds, short toTransparency, TweenTiming timing, TweenStyle style) {
  return TweenCharacterTransparency(this, seconds, toTransparency, timing, style);
}

int TweenZOrder(this GUI*, float seconds, short toZOrder, TweenTiming timing, TweenStyle style) {
  return TweenGUIZOrder(this, seconds, toZOrder, timing, style);
}

int TweenImage(this Object*, Object* tmpObjectRef, float seconds, short toSprite, TweenTiming timing, TweenStyle style) {
  return TweenObjectImage(this, tmpObjectRef, seconds, toSprite, timing, style);
}

int TweenAnimationSpeed(this Character*, float seconds, short toAnimationSpeed, TweenTiming timing, TweenStyle style) {
  return TweenCharacterAnimationSpeed(this, seconds, toAnimationSpeed, timing, style);
}

int TweenSize(this GUI*, float seconds, short toWidth, short toHeight, TweenTiming timing, TweenStyle style) {
  return TweenGUISize(this, seconds, toWidth, toHeight, timing, style);
}

int TweenSize(this Label*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenLabelSize(this, seconds, toX, toY, timing, style);
}

int TweenSize(this Button*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenButtonSize(this, seconds, toX, toY, timing, style);
}

int TweenSize(this TextBox*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenTextBoxSize(this, seconds, toX, toY, timing, style);
}

int TweenSize(this ListBox*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenListBoxSize(this, seconds, toX, toY, timing, style);
}

int TweenSize(this Slider*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenSliderSize(this, seconds, toX, toY, timing, style);
}

int TweenSize(this InvWindow*, float seconds, short toX, short toY, TweenTiming timing, TweenStyle style) {
  return TweenInvWindowSize(this, seconds, toX, toY, timing, style);
}

int TweenScaling(this Character*, float seconds, short toScaling, TweenTiming timing, TweenStyle style) {
  return TweenCharacterScaling(this, seconds, toScaling, timing, style);
}

int TweenLightLevel(this Region*, float seconds, short toLightLevel, TweenTiming timing, TweenStyle style) {
  return TweenRegionLightLevel(this, seconds, toLightLevel, timing, style);
}

int TweenTintR(this Region*, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  return TweenRegionTintR(this, seconds, toR, timing, style);
}

int TweenTintG(this Region*, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  return TweenRegionTintG(this, seconds, toG, timing, style);
}

int TweenTintB(this Region*, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  return TweenRegionTintB(this, seconds, toB, timing, style);
}

int TweenTintAmount(this Region*, float seconds, short toAmount, TweenTiming timing, TweenStyle style) {
  return TweenRegionTintAmount(this, seconds, toAmount, timing, style);
}

int TweenTintBlackAndWhite(this Region*, float seconds, TweenTiming timing, TweenStyle style) {
  return TweenRegionTintBlackAndWhite(this, seconds, timing, style);
}

int TweenColorR(this Label*, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  return TweenLabelColorR(this, seconds, toR, timing, style);
}
int TweenColorG(this Label*, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  return TweenLabelColorG(this, seconds, toG, timing, style);
}
int TweenColorB(this Label*, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  return TweenLabelColorB(this, seconds, toB, timing, style);
}
int TweenColorR(this Button*, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  return TweenButtonColorR(this, seconds, toR, timing, style);
}
int TweenColorG(this Button*, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  return TweenButtonColorG(this, seconds, toG, timing, style);
}
int TweenColorB(this Button*, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  return TweenButtonColorB(this, seconds, toB, timing, style);
}
int TweenColorR(this TextBox*, float seconds, short toR, TweenTiming timing, TweenStyle style) {
  return TweenTextBoxColorR(this, seconds, toR, timing, style);
}
int TweenColorG(this TextBox*, float seconds, short toG, TweenTiming timing, TweenStyle style) {
  return TweenTextBoxColorG(this, seconds, toG, timing, style);
}
int TweenColorB(this TextBox*, float seconds, short toB, TweenTiming timing, TweenStyle style) {
  return TweenTextBoxColorB(this, seconds, toB, timing, style);
}

int TweenSelectedItem(this ListBox*, float seconds, short toSelectedItem, TweenTiming timing, TweenStyle style) {
  return TweenListBoxSelectedItem(this, seconds, toSelectedItem, timing, style);
}
int TweenTopItem(this ListBox*, float seconds, short toTopItem, TweenTiming timing, TweenStyle style) {
  return TweenListBoxTopItem(this, seconds, toTopItem, timing, style);
}
int TweenTopItem(this InvWindow*, float seconds, short toTopItem, TweenTiming timing, TweenStyle style) {
  return TweenInvWindowTopItem(this, seconds, toTopItem, timing, style);
}

int TweenValue(this Slider*, float seconds, short toValue, TweenTiming timing, TweenStyle style) {
  return TweenSliderValue(this, seconds, toValue, timing, style);
}
int TweenHandleOffset(this Slider*, float seconds, short toHandleOffset, TweenTiming timing, TweenStyle style) {
  return TweenSliderHandleOffset(this, seconds, toHandleOffset, timing, style);
}

function StopAllTweens(this GUI*, TweenStopResult result) {
  TweenStopAllForGUI(this, result);
}

function StopAllTweens(this Object*, TweenStopResult result) {
  TweenStopAllForObject(this, result);
}

function StopAllTweens(this Character*, TweenStopResult result) {
  TweenStopAllForCharacter(this, result);
}

function StopAllTweens(this Region*, TweenStopResult result) {
  TweenStopAllForRegion(this, result);
}

function StopAllTweens(this Label*, TweenStopResult result) {
  TweenStopAllForLabel(this, result);
}

function StopAllTweens(this Button*, TweenStopResult result) {
  TweenStopAllForButton(this, result);
}

function StopAllTweens(this TextBox*, TweenStopResult result) {
  TweenStopAllForTextBox(this, result);
}

function StopAllTweens(this ListBox*, TweenStopResult result) {
  TweenStopAllForListBox(this, result);
}

function StopAllTweens(this Slider*, TweenStopResult result) {
  TweenStopAllForSlider(this, result);
}

function StopAllTweens(this InvWindow*, TweenStopResult result) {
  TweenStopAllForInvWindow(this, result);
}
#endif
#endif

